<template>
  <div>
    <div class="code-container" ref="container"></div>
  </div>
</template>
 
<script>
// import './icon/iconfont.css'
import * as monaco from 'monaco-editor'
export default {
  name: 'codeEditor',
  props: {
    opts: {
      type: Object,
      default() {
        return {
          language: 'java', // shell、sql、python
          readOnly: false, // 不能编辑
        }
      },
    },
    value:{
      type:String,
      default:''
    }
  },
  watch: {
    value: {
      handler(n) {
        if(this.showInit){//初次传值初始化一次
          this.init()
          this.showInit = false
        }
        this.monacoInstance.setValue(n)//剩余全部更新内容
      },
      deep: true,
    },
  },
  data() {
    return {
      monacoInstance: null,
      provider: null,
      hints: [],
      color: null,
      showInit:true
    }
  },
  mounted() {
    this.init()
  },
  beforeDestroy() {
    this.dispose()
  },
 
  methods: {
    cloneDeep(suggestions) {
      return JSON.parse(JSON.stringify(suggestions))
    },
    dispose() {
      if (this.monacoInstance) {
        if (this.monacoInstance.getModel()) {
          this.monacoInstance.getModel().dispose()
        }
        this.monacoInstance.dispose()
        this.monacoInstance = null
        if (this.provider) {
          this.provider.dispose()
          this.color.dispose()
          this.provider = null
        }
      }
    },
    init() {
      console.log('-----', monaco, monaco.editor)
      let that = this
      this.dispose()
      this.provider = monaco.languages.registerCompletionItemProvider('java', {
        provideCompletionItems(model, position) {
          console.log('model', model)
          console.log('position', position)
          // 获取当前行数
          const line = position.lineNumber;

          // 获取当前列数
          const column = position.column;
          // 获取当前输入行的所有内容
          const content = model.getLineContent(line)
          // 通过下标来获取当前光标后一个内容，即为刚输入的内容
          const sym = content[column - 2];
          var textUntilPosition = model.getValueInRange({
            startLineNumber: 1,
            startColumn: 1,
            endLineNumber: position.lineNumber,
            endColumn: position.column
          });
          var word = model.getWordUntilPosition(position);
          var range = {
            startLineNumber: position.lineNumber,
            endLineNumber: position.lineNumber,
            startColumn: word.startColumn,
            endColumn: word.endColumn
          };
          //---------------------------------------------------
          //上面的代码仅仅是为了获取sym，即提示符
          //---------------------------------------------------
          var suggestions = [];
          if (sym === ".") {
            console.log('======1')
            //...
            //拦截到用户输入$，开始设置提示内容，同else中代码一致，自行拓展
          } else {
            //直接提示，以下为sql语句关键词提示
            // var sqlStr = [
            //     'SELECT', 'FROM', 'WHERE', 'AND',
            //   'OR', 'LIMIT', 'ORDER BY', 'GROUP BY',
            //   'LEFT', 'ON', 'if(){}', 'for(){}',
            //   'size', 'get()', 'substring', 'return'
            // ];
            let tipsArray =[
              {label: 'salience', detail: '用于指定规则的执行优先级'},
              {label: 'dialect', detail: '用于指定当前规则使用的语言类型，取值为java和mvel，默认值为java'},
              {label: 'no-loop', detail: '防止死循环'},
              {label: 'enabled', detail: '是否被激活'},
              {label: 'lock-on-active', detail: 'lock-on-active'}
            ]
            for (var i in tipsArray) {
              suggestions.push({
                label: tipsArray[i].label, // 显示的提示内容
                kind: monaco.languages.CompletionItemKind['Function'], // 用来显示提示内容后的不同的图标
                insertText: tipsArray[i].label, // 选择后粘贴到编辑器中的文字
                detail: tipsArray[i].detail, // 提示内容后的说明
                range: range
              });
            }
          }
          return {
            suggestions: suggestions
          };
          // return {
          //   suggestions: vCompletion,//自定义语法提示，代码补全
          // }
        },
        triggerCharacters: ['.'],//输入点可触发代码提示
      })
        //自定义语法高亮
      this.color = monaco.languages.setMonarchTokensProvider('java', {
        ignoreCase: true,
        tokenizer: {//需要什么颜色，就在里面用正则匹配
          root: [
            [
              /currentUser|#@|RsOk|#string|#switch|#case|selectSql|uuid|addOrderBy|addConditionRequired|countSql|addGroupBy|currentDateTime|addFieldExist|formData|simplePage|RsJson|[@]|RsJsonData|Local|select|#set|#include|#render|#end|#for|#if|#else|#elseif|from|where|addField|addConditionExist|table|SqlUtil|GROUP_CONCAT|BY|AND|ADD|Data|page|IF|as|SUM|MAX|min|AVG|COUNT|ROUND|LEFT|JOIN|timer/,
              { token: 'keyword' },
            ], //蓝色
            [
              /salience|dialect/,
              { token: 'comment' },
            ],
            [
              /[+]|[-]|[*]|[/]|[%]|[>]|[<]|[=]|[!]|[:]|[&&]|[||]/,
              { token: 'string' },
            ], //红色
            [/'.*?'|".*?"/, { token: 'string.escape' }], //橙色
            [/#--.*?\--#/, { token: 'comment' }], //绿色
            [/null/, { token: 'regexp' }], //粉色
            [/[{]|[}]/, { token: 'type' }], //青色
            // [/[\u4e00-\u9fa5]/, { token: 'predefined' }],//亮粉色
            // [/''/, { token: 'invalid' }],//红色
            // [/[\u4e00-\u9fa5]/, { token: 'number.binary' }],//浅绿
            [/(?!.*[a-zA-Z])[0-9]/, { token: 'number.hex' }], //浅绿
            [/[(]|[)]/, { token: 'number.octal' }], //浅绿
            [/[\u4e00-\u9fa5]/, { token: 'number.float' }],//浅绿
          ],
        },
      })
      // 初始化编辑器实例
      this.monacoInstance = monaco.editor.create(this.$refs['container'], {
        value: this.value,
        theme: 'vs-dark',
        autoIndex: true,
        ...this.opts,
      })
      // 监听编辑器content变化事件
      this.monacoInstance.onDidChangeModelContent(() => {
        this.$emit('contentChange', this.monacoInstance.getValue())
      })
//       monaco.editor.defineTheme("newTheme", {
//       base: 'vs',
//       inherit: false,
//       rules: [
//             { token: 'key', foreground: '#0000FF', fontStyle: 'bold' },
//             { token: 'sym', foreground: '#f5a623', },
//             { token: 'value', foreground: '#4EC9B0' },
//             { token: "notes", foreground: "#6A9955" },
//             { token: "comment", foreground: "#6A9955" },
//       ]
// });
    },
  },
}
</script>


<style lang="less" scope>
.code-container {
  width: 100%;
  height: 500px;
  overflow: hidden;
  border: 1px solid #eaeaea;
  .monaco-editor .scroll-decoration {
    box-shadow: none;
  }
}
</style>